package com.alibaba.csp.sentinel.dashboard.controller;

import com.alibaba.csp.sentinel.dashboard.auth.AuthAction;
import com.alibaba.csp.sentinel.dashboard.auth.AuthService;
import com.alibaba.csp.sentinel.dashboard.datasource.entity.rule.RuleEntity;
import com.alibaba.csp.sentinel.dashboard.domain.Result;
import com.alibaba.csp.sentinel.dashboard.repository.rule.RuleRepository;
import com.alibaba.csp.sentinel.dashboard.rule.DynamicRuleProvider;
import com.alibaba.csp.sentinel.dashboard.rule.DynamicRulePublisher;
import com.alibaba.csp.sentinel.util.StringUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;

import javax.annotation.Resource;
import java.util.List;


/**
 * @author: shaozeming
 * @date: 2022/8/8 14:37
 * @description:
 **/

public  class RuleController<T extends RuleEntity,M extends RuleRepository<T,Long>> {

    private static final Logger logger = LoggerFactory.getLogger(RuleController.class);


    @Resource
    protected DynamicRuleProvider<List<T>> ruleProvider;

    @Resource
    protected DynamicRulePublisher<List<T>> rulePublisher;



    @Autowired
    protected M repository;



    @GetMapping({"/rules","/rules.json","/list.json"})
    @AuthAction(AuthService.PrivilegeType.READ_RULE)
    public Result<List<T>> apiQueryAllRulesForMachine(@RequestParam String app,
                                                                        @RequestParam String ip,
                                                                        @RequestParam Integer port) {
        if (StringUtil.isEmpty(app)) {
            return Result.ofFail(-1, "app cannot be null or empty");
        }
        if (StringUtil.isEmpty(ip)) {
            return Result.ofFail(-1, "ip cannot be null or empty");
        }
        if (port == null || port <= 0) {
            return Result.ofFail(-1, "Invalid parameter: port");
        }
        try {
            List<T> rules = repository.findAllByApp(app);
            return Result.ofSuccess(rules);
        } catch (Throwable throwable) {
            logger.error("Error when querying  rules", throwable);
            return Result.ofFail(-1, throwable.getMessage());
        }
    }


    protected void publishRules(String app,Class<T> clz) {

        List<T> appRuleList = repository.findAllByApp(app);
        try {
            rulePublisher.publish(app, appRuleList,clz);
        } catch (Exception e) {
            logger.info("publish rules failed",e);
        }
    }

}
